package com.jiunuan.live.core.server.handler.impl;

import com.jiunuan.live.core.server.common.ImMsg;
import com.jiunuan.live.core.server.handler.ImHandlerFactory;
import com.jiunuan.live.core.server.handler.SimplyHandler;
import com.jiunuan.live.im.constants.ImMsgCodeEnum;
import org.springframework.context.ApplicationContext;
import io.netty.channel.ChannelHandlerContext;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: JiuNuan
 * @CreateTime: 2024-08-10 21:55
 * @Description: 消息工厂实现类
 */
@Component
public class ImHandlerFactoryImpl implements ImHandlerFactory , InitializingBean {
    private static final Map<Integer,SimplyHandler> simplyHandlerMap = new HashMap<>();
    @Resource
    private ApplicationContext applicationContext;
    @Override
    public void doMsgHandler(ChannelHandlerContext ctx, ImMsg imMsg) {
        SimplyHandler simplyHandler = simplyHandlerMap.get(imMsg.getCode());
        if(simplyHandler == null){
            throw new IllegalArgumentException("msg code is error,code is:" + imMsg.getCode());
        }
        simplyHandler.handler(ctx, imMsg);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 登录消息包，登录token认证，channel 和 userId 关联
        simplyHandlerMap.put(ImMsgCodeEnum.IM_LOGIN_MSG.getCode(),      applicationContext.getBean(LoginMsgHandler.class));
        // 登出消息包，正常断开im连接时发送，释放系统的资源
        simplyHandlerMap.put(ImMsgCodeEnum.IM_LOGOUT_MSG.getCode(),     applicationContext.getBean(LogoutMsgHandler.class));
        // 业务消息包（最常用），如im发送数据或接收数据
        simplyHandlerMap.put(ImMsgCodeEnum.IM_BIZ_MSG.getCode(),        applicationContext.getBean(BizImMsgHandler.class));
        // 心跳消息包，定时发送消息，用于检测连接是否正常，如果超过一定时间没有收到心跳包，则断开连接
        simplyHandlerMap.put(ImMsgCodeEnum.IM_HEARTBEAT_MSG.getCode(),  applicationContext.getBean(HeartBeatImMsgHandler.class));
        // ack消息包，用于接收客户端的ack消息，客户端收到服务端发送的消息后，发送ack消息给服务端，服务端收到ack消息后，删除对应的消息
        simplyHandlerMap.put(ImMsgCodeEnum.IM_ACK_MSG.getCode(),        applicationContext.getBean(AckImMsgHandler.class));
    }
}
